 /*@Author S.Genikhov*
  Creation Date 19/06/2010
  Last modifed  25/06/2010
  @St_Schelduler run function of type func with some repeatablity provided by user*/
#ifndef ST_SCHELDULER_INCLUDED
#define ST_SCHELDULER_INCLUDED

#define INOUT

#include <stdio.h>


#include <Queueinside.h>
#include <MemoryManager.h>
#include <UserAPI.h>
#include <vfsystem.h>

#define  INOUT
#define  Qitems          (3)
#define  sizeFD          (2)
#define  Buffersize      (40)/*its the lenght of "buffer" in Variable and also
                                will be size of size lenght_of_file in IOrequest
                                 that Dirver will read*/
#define IOBUFSIZE        (4)/*The maximal lenght that drive capable to read in one access*/







typedef enum err_Sch{
SCHELDULER_PROBLEMS                  =3,
ST_TASK_INSTERTION_PROBLEMS          =4,
ST_BLOCKQ_INSERTION_PROBLEMS         =5,
ST_EMPTY_USER_DATA_SENDING           =8,
ST_ALLOCATION_USERDATA_PROBLRMS      =10,
ST_TASK_KREATION_PROBLEMS            =30,
NOT_ACCEPTED_BLOCKQ                  =40,
NOT_ACCEPTED_BTASK                   =50,
ST_MEMMANAGER_MEM_ALLOCATION_PROBLEMS=60,
ST_OPEN_FILe_MEMORY_PROBLEMS         =70
} err_Sch;

typedef enum readystatus{ready,notready} readystatus;
typedef enum isfileopen {closed,opened}     isfileopen;

typedef struct File_Descriptor File_D;
typedef struct ST_Task ST_Task;
typedef struct Sch_Schelduler Sch_Schel;

/*Type of Schelduler comparison insertion function*/
typedef err_Sch (*ST_CompInsertF)(Sch_Schel* Sch);
/*Schelduler comparison insertion function*/
err_Sch Sch_Schelduling(Sch_Schel* Sch);


struct variable
{
    size_t if_file_open;/*open file or not open*/
    int    fdnumber;/*index of open file  for read file*/
    char   buffer[Buffersize];
};

/*
struct File_Descriptor/*content of file here is the golbal variable*
{
    char  name[10];/*File name*
    int   pos;/*position in file during reading*
};
*/
struct ST_Task
{
    double                nextrun;/*msec scale*/
    void*                 userdata;
    size_t                period;/*msec scale*/
    func                  ST_func;
    FD*                   FD[sizeFD];
    size_t                is_reschdeldular;/* if its 1 it can be inserted into ready Q*/
    MMheap*               MM_Man;
    int                   taskID;/*For debug*/
};

typedef struct IOReq
{
    size_t    n_readed;/*how much already was readed*/
    char*      buf;/*capability of driver to read in one cycle*/
    size_t    lenght_of_open_file;/*lenght of characters in open file*/
    ST_Task*  Task;
    size_t    indexFD;
    size_t    debugcount;
} IOReq;

/*container to create and coardinate the queue of different functions,
every item of PQ is function*/
struct Sch_Schelduler
{
    PQ*               readyQ;/*que of readytasks*/
    size_t            readyQ_size;
    PQ*               blockQ;/*Que of IOstructs*/
    size_t            blockQ_size;
    ST_Task*          running;
    ST_CompInsertF    STfunc;
    int               PIDofTask;/*for Debug*/
};

struct Kernel
{
    Sch_Schel* ST;
};


/*Building of Shchelduler, the driver function will be added during initiation*/
err_Sch Sch_Initiate(Sch_Schel* Sch,func DRIVER,size_t Driver_period);
/*Inserting function to Scheludler  mperiond in msec, minimu 1 max 10000*/
err_Sch Sch_InsertTask(Sch_Schel* Sch,func Taksfunc,size_t mperiod,void* data);

/*By using of non standard que function abble to pop form index and push to index*/
/*Find the someTask will be prepend to task with a higher nexrunt, using of function ST_CompInsertF*/
err_Sch Sch_InsertTask_inRightplace_to_Queue(PQ* _Que,size_t* readyQ_size,ST_Task* someTask);

/*Insert in blocking Q in a standard Queu way*/
err_Sch Sch_InsertTask_to_blockQ(PQ* _Bq, IOReq* _IOBtask);
/*Destroy of Schelduler*/
void Sch_Destroy(Sch_Schel* Sch);
#endif /* ST_SCHELDULER_INCLUDED*/
